package com.cts.learninglibrary.config.shiro.server;

import com.cts.learninglibrary.pojo.User;
import com.cts.learninglibrary.util.CommonConverterUtil;
import com.cts.learninglibrary.util.JsonUtil;
import com.cts.learninglibrary.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * @author arctique
 * @date 2020/8/24 9:28
 */
@Configuration
@Slf4j
public class LoginFilter extends AccessControlFilter {

    private final String SESSION_KEY = "SESSION_KEY:";

    @Autowired
    private RedisUtil redisUtil;

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {

        log.info("----------进入登录拦截器----------");

        Subject subject = getSubject(servletRequest, servletResponse);
        Object o = subject.getPrincipal();
        User user = CommonConverterUtil.convert(o, User.class);
        log.info("[登录拦截-用户信息] : {}", JsonUtil.objToString(user));

        if (user == null) {
            WebUtils.issueRedirect(servletRequest, servletResponse, "/user/notLogin");
            return false;
        } else {
            // 获取当前sessionId
            String sessionId = subject.getSession().getId().toString();
            // 查询redis缓存中的sessionId
            System.out.println(redisUtil.hasKey(SESSION_KEY + user.getUsername()));
            String realSessionId = (String) redisUtil.get(SESSION_KEY + user.getUsername());

            if (sessionId.equals(realSessionId)) {
                log.info("[正常访问]");
                redisUtil.expire(SESSION_KEY + user.getUsername(), 3600L);
                return true;
            } else {
                log.warn("[用户踢出]");
                subject.logout();
                WebUtils.issueRedirect(servletRequest, servletResponse, "/user/kickOut");
                return false;
            }
        }
    }

    public void setRedisTemplateService(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }
}
